package com.jianyushe.gof23.learncode.creationalpattern.singleton;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author Create by Alvin
 * @Description 通过反射破解单例
 * @date 2021-10-09 17:24
 */
public class CrackSingleTonTest {
    /**
     * 饿汉模式
     */
    static class HungryInstanceCrack {
        private static final Logger LOGGER = LoggerFactory.getLogger(HungryInstanceCrack.class);
        // 饿汉模式  即时加载(没有延时加载（懒加载）优势) 如果没被调用则浪费资源
        // warning原因 是因为new 对应的Class中 只包含了静态变量，静态方法，idea认为你没有必要去new 出来一个对象，所以进行了提示。
        // 解决方法 只要在对象中加入一些实例变量和方法就可以了。
        private static final HungryInstanceCrack INSTANCEOFHUN = new HungryInstanceCrack();

        HungryInstanceCrack() {
            LOGGER.info("单利饿汉模式创建对象...");
        }

        // 方法没同步，调用效率高
        public static HungryInstanceCrack getHungryInstance() {
            return INSTANCEOFHUN;
        }
    }

    @Test
    public void crackTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<HungryInstanceCrack> forNameClass = (Class<HungryInstanceCrack>) Class.forName("com.jianyushe.gof23.learncode.creationalpattern.CrackSingleTonTest.HungryInstanceCrack");
        Constructor<HungryInstanceCrack> declaredConstructor = forNameClass.getDeclaredConstructor(null);

        HungryInstanceCrack hungryInstanceCrack = declaredConstructor.newInstance();
        HungryInstanceCrack hungryInstanceCrack2 = declaredConstructor.newInstance();
        System.out.println(hungryInstanceCrack);
        System.out.println(hungryInstanceCrack2);
    }

}
